fix(ode): validate ExponentialMap::integrate_attitude's timestep and … - #307
fix(ode): validate ExponentialMap::integrate_attitude's timestep and …#307naseem173 wants to merge 5 commits into
Conversation
…rate Fixes kmolan#302. attitude_step and attitude_step_with_angular_acceleration fed a timestep and angular rate straight into SO3::exp with no validation: a non-finite rate produced a quaternion of NaNs that never recovered, and a non-positive timestep integrated backwards (or not at all) without comment. attitude_step and attitude_step_with_angular_acceleration stay infallible, since they sit on RigidBody::stepped's documented panic-free per-tick path (and estimation::attitude_correction's per-tick path) - making them fallible would force that hot loop to become fallible too. Their docs now carry an explicit "Behavior" note describing the NaN policy instead of leaving it silent. integrate_attitude, the multi-step driver (not used on any per-tick hot path, and already the same shape as the fallible Rk45::solve), now validates dt up front and the rate returned by its angular_rate_at callback on every step, returning the new IntegrateError::NonPositiveTimestep or the existing IntegrateError::NonFinite instead of silently producing garbage.
|
@naseem173 thanks for the contribution, please address existing failures before I review the changes. Looks like you need to run |
- error.rs: fix indentation of the NonPositiveTimestep Display arm
- tests/suite/ode/exponential_map.rs: fix import order and split
chained .unwrap() calls per rustfmt
- tutorials/ode-integrators.md: add .unwrap() to the now-fallible
integrate_attitude doctest call, and update the "Errors" paragraph
to reflect that attitude_step/attitude_step_with_angular_acceleration
stay infallible while integrate_attitude now returns IntegrateError
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
Thanks for the review! I've run |
Result is already #[must_use]; the extra attribute trips clippy::double_must_use under -D warnings. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
Pushed a follow-up (commit 07aa5c4): |
…rate
Fixes #302. attitude_step and attitude_step_with_angular_acceleration fed a timestep and angular rate straight into SO3::exp with no validation: a non-finite rate produced a quaternion of NaNs that never recovered, and a non-positive timestep integrated backwards (or not at all) without comment.
attitude_step and attitude_step_with_angular_acceleration stay infallible, since they sit on RigidBody::stepped's documented panic-free per-tick path (and estimation::attitude_correction's per-tick path) - making them fallible would force that hot loop to become fallible too. Their docs now carry an explicit "Behavior" note describing the NaN policy instead of leaving it silent.
integrate_attitude, the multi-step driver (not used on any per-tick hot path, and already the same shape as the fallible Rk45::solve), now validates dt up front and the rate returned by its angular_rate_at callback on every step, returning the new IntegrateError::NonPositiveTimestep or the existing IntegrateError::NonFinite instead of silently producing garbage.
What & why
Adds input validation to
ExponentialMap::integrate_attitudeper #302, without changing the infallible signature of the per-tick primitives it's built from. See the commit message above for the full reasoning on scope.Checklist
cargo test+cargo clippy --all-targetsclean locally (not run locally in this environment — relying on CI to verify; happy to fix any failures)unwrap/expect/panicon library paths (typed errors instead)